# Agent Bash 工具工程化：后台运行与沙盒权限设计

在上一篇文章中，我们对于Bash工具的简单设计做了一个整理，这种思路设计出来的Bash工具，只能跑一跑demo或者在项目前期的构建阶段“性价比很高”，但是如果要追求线上级的Agent的运行稳定，那么Bash工具最重要的两环是必不可少的：**后台运行和沙盒设计**


参考分析资料：

- 《上一篇：Bash工具实现和安全设计》：：[Bash工具实现和安全权限设计细节](./Bash工具实现和安全权限设计细节.md)

- 《Anthropic的轻量级沙箱工具》：https://github.com/anthropic-experimental/sandbox-runtime

- 《文中Excaildraw文件链接》：[Bash工具的沙盒设计和后台运行excalidraw](https://my.feishu.cn/file/QalHbNySfo3zVqxTIprcQcSJnSh)

## 一、上下文管理 \- 后台运行

![上下文管理](./image/agentbash1.PNG)

Bash工具是用来执行终端命令的，有一些项目启动命令，会持续执行很久，如果没有blockMs前台执行时间限制，那么bash工具的执行就会被卡住，**有了blockMs的话，就可以将命令的执行挂载到后台去**



同时我们也可以发现，有时候会在终端调用读取命令，有可能会读取很大的文件，所以对于Bash工具的输出是有限制的，当超过一个阈值\(目前设计的是4000），**就将bash工具的结果先写入到临时文件中去，返回结果的时候将临时文件路径返回**，模型在需要的时候会自动调用相应工具读取的



那么我们回到具体的两个关键设计点中：**挂载后台和写入临时文件**

1. 写入临时文件可以防止内存被撑爆，同时也可以提高上下文的效率，只让必要的信息进入上下文，只在必要的时候读取

2. 挂载后台，这一步最关键的是挂载之后，模型如何获取后台命令的执行情况，当然模型可以主动根据文件路径进行读取，但是这样的效率不高，所以我们设计了**增量读取工具**`bash_output`**和事件订阅推送**



增量读取工具bash\_output，它可以高效的返回增量信息，而不是全部的文件内容，同时也可以返回后台执行的任务状态，提供给模型判断任务情况，比一般的读取工具返回的结果更有意义一些



事件订阅推送的实现是：每一次将bash工具的输出写入到临时文件的时候，会触发一个规则判断（正则判断或者状态判断），当条件符合的时候，那么该函数就会将bash工具输出的这一部分信息推送到下一轮的turn中的上下文。

> 我们的设计中，没有采用模型定时轮询任务状态，这样效率太低啦，应该是载触发一定条件的时候，任务侧主动推送。
> 
> 



## 二、沙盒与权限设计

沙盒和权限设计管的侧重点是不同的

- 权限设计管的是：这个命令需不需要用户审核一下，这个命令是否可以执行

- 沙盒设计管的是：这个命令执行之后，能影响的程度有多大，保证命令执行兜底的安全



在mac系统中，可以使用内置的沙盒机制来实现，用一份命令启动的Profile语法文件规则就可以，

> 具体的使用也很简单，在执行命令的时候/`usr/bin/sandbox-exec -f profile.sb`来启动进程，约束是由内核来完成的，并且会自动继承到整个进程树中去
> 
> 

沙盒中的这份Profile语法文件，是参考了一下anthropic开源的一个轻量级沙盒库中的核心规则，不太想直接使用开源库来实现，因为我希望自己这份沙盒配置文件可以足够的透明



那么完整的设计结合思路如下：一共是三层设计，先进行常规的危险命令的执行拦截，然后先在沙盒中执行命令，如果沙盒中因为权限不足执行失败，那么在进入到真实环境中执行命令，但是在执行之前都要ask一下用户

![沙盒权限的层级限制](./image/agentbash2.PNG)

在沙盒因为权限执行失败的时候，要记得转换一下失败输出的信号，不然Agent拿到EPERM这种错误信息，会认为是执行命令书写错误导致的，而不是因为沙盒权限不足导致的，**所以我们要添加一段提示信息“这可能是沙盒拦的，不是命令错了”**

